#ifndef VPCONN_H
#define VPCONN_H

#include "connect.h"

#define APP1		(uint8)'V'
#define APP2		(uint8)'P'

#define GAMEID			16	// Class/Player limits gameId

class VPGame;
class VPHand;
class VPokerOpts;
class VPokerSavedGame;
class ShueSave;

class VPConnection : public Connection
{
	public:
		VPConnection(Server* server, SOCKET client);
		~VPConnection();

		void msgStart();
		void msgAdd(uint8 Byte);
		void msgAdd(int32 SignedLong);
		uint8* msgGetBuf();
		void msgReleaseBuf(int32 Amt);
		void msgEnd();

		enum trackNewGameResult { TNG_OK, TNG_NOMONEY, TNG_FAILED };
		int32	trackNewGame(int32 bet, VPHand* dealt, VPokerSavedGame* saved,
					int32 *balance);
		bool8	trackDrawHand(uint8 nhand, VPHand* drawn, int32 payout, int32 paytype );
		bool8	trackDrawHandRollBack();
		bool8	trackDrawDone(int32 payout,	bool8 dblUpActive, int32* balance);
		bool8	trackDoubleUpDeny(int32 payout,
					int32* balance);
		bool8	trackDoubleUpDeal(int32 round, uint8 dealt, ShueSave*,
					int32* balance);
		bool8	trackDoubleUpDraw(int32 round, uint8 drawn, int32 winResult,
					int32 payout,
					int32* balance);
		bool8	trackNewSubGame();
		bool8	trackGetSubGame();
		
		bool8	getDrawnCards( uint8 cards[100][5], int32*,int32*,int32* );

        bool8 isForMoney();
		bool8 shouldSaveGameData();

		int32	getDoubleUpCapAmount()		{ return dlbUpCapAmount;	}

		enum 
		{
			MAX_SUBGAME_DATA=5
		};

	protected:
		bool8	getResponse();

		void	sendStopMsg();

		void	gameOver();

		bool8	parseAnsiCasinoLogin( int32*);
		bool8	parseUnicodeCasinoLogin( int32*);
		bool8   parseReloadDenomination(int32*);	// CSN-13423: reload with a new denomination
		void	removeCasinoSpecific();

		int32	encode(uint8*, uint8*, int32);
		int32	decode(uint8*, uint8*, int32);

		bool8	trackGetBalance(int32 *);
		bool8	trackGetOptions(VPokerOpts*, uint8 machId,uint8 nHands, int32 creditValue);
		bool8	trackGetPlayerLimits(uint8 machId, int32* compFactor);
		bool8	trackHasSavedGame(int32* err);
		void	trackaddBadPacket(int32 error_reason, char MessageType, char *msgbuf, int32 msglen);
		int32	trackValidateLogin();
		int32	trackValidateSession();

		// CSN-7075: New Authentication
		void	trackLogoutSession();

		//Signals from server to player
		void	Answer( uint8 ans );	//generic message
		void	Error( int err );		//error message

		void	HandlePlayerUnknown();	//Unknown
		void	HandlePlayerAnsiLogin	();	//Login
		void	HandlePlayerUnicodeLogin();	//login
		void    HandleReloadDenomination();	// CSN-13423: change denomination in MHVPoker
		void	HandlePlayerLogin(bool isReload = false);

		void	allocateXMLTranslator( XMLTranslator** );

	protected:
		enum Flags
		{
			LOGGEDON		= 0x1L,
			PAYTABLECHANGED	= 0x02L,
			DBLUPCHANGED	= 0x04L
		};

		uint32 flags;
		int32 machId;
		int32 creditValue;	// in cents: 25==quarter
		int32 payTableFreq;	// lo, med, hi
		uint8 nHands;
		int32 dblUpEnabled;
		int32 dlbUpCapAmount;
		int32 compFactor;
		VPGame* game;
		void* casinoSpecific;
		int32 msglen;
		uint8 msgbuf[OUTMAX];

		uint8		subGameData[MAX_SUBGAME_DATA];
		int32		subGameLength;

        uint8   m_ucProtoVer1;                  // major part of protocol version being used to communicate with client.
        uint8   m_ucProtoVer2;                  // minor part of protocol version being used to communicate with client.
        #ifdef FORCEDSHOE 
        String  m_pid;
        #endif

	public:
		int creditsToCents(int cred) { return cred*creditValue; }

		// truncates (floor) value since fractional credits not allowed
		//
		int centsToCredits(int cents) { return cents/creditValue; }

		uint8 getMachId() { return (uint8)(machId & 0xffL); }
        
        #ifdef FORCEDSHOE 
        String  GetPID() {return m_pid;}
        #endif

		int32 getPayTableFreq() { return payTableFreq; }

		int32 getMaxBet() { return 5; }		// currently, 5 credits max
		
		uint8* getSubGameData()   { return subGameData;    }
		int32  getSubGameLength() { return subGameLength;  }
		int32* getSubGameLengthByRef() { return &subGameLength; }

	// [AO 2008-01-16] Refactoring for HA
	private:
		bool ValidateSession();
};

#endif
